﻿using System.Collections.Generic;
using System.Linq;

using Gonte.Data.DataService;
using Gonte.Data.Metadata;
using Gonte.Data;

namespace Gonte.Desktop.DataAccess
{
    public class MockDataService
        : IDataService
    {
        IList<DataRecord> _records;
        int _sequence;

        public MockDataService()
        {
            // Create in memory record
            _records = new List<DataRecord>();

            int count = 10000;
            _sequence = count;
            for (int i = 1; i <= count; ++i)
            {
                DataRecord record = new DataRecord
                {
                    Identifiers = new List<DataField>
                    {
                        new DataField
                        {
                            Name = "Id",
                            Value = i
                        }
                    },
                    Fields = new List<DataField>()
                };

                for (int j = 1; j <= 20; ++j)
                {
                    DataField field = new DataField
                    {
                        Name = string.Format("Field{0}", j),
                        Value = string.Format("String {0}-{1}", i, j)
                    };

                    record.Fields.Add(field);
                }

                _records.Add(record);
            }
        }

        private bool AreSame(IList<DataField> ids1, IList<DataField> ids2)
        {
            if (ids1.Count != ids2.Count)
            {
                return false;
            }

            int count = ids1.Count;

            for (int i = 0; i < count; ++i)
            {
                DataField df1 = ids1[i];
                DataField df2 = ids2[i];

                if (!df1.Equals(df2))
                {
                    return false;
                }
            }

            return true;
        }

        public Domain GetMetadata()
        {
            Domain domain = new Domain
            {
                Name = "My Domain",
                FullName = "Gonte.MyDomain",
                Entities = new List<Entity>()
            };

            for (int i = 0; i < 162; ++i)
            {
                int id = i + 1;

                Entity entity = new Entity
                {
                    Name = string.Format("Entity {0}", id),
                    FullName = string.Format("Application1.Entity{0}", id),
                    Attributes = new List<Attribute>()
                };

                for (int j = 0; j < 20; ++j)
                {
                    int eid = j + 1;

                    if (eid % 3 == 0)
                    {
                        Attribute attribute = new Attribute
                        {
                            Name = string.Format("Field{0}", eid), // No spaces allowed for the name of the attribute
                            Category = Attribute.Categories.Complex,
                            TypeName = "Application1.Entity3"
                        };

                        entity.Attributes.Add(attribute);
                    }
                    else if (eid % 5 == 0)
                    {
                        Attribute attribute = new Attribute
                        {
                            Name = string.Format("Field{0}", eid), // No spaces allowed for the name of the attribute
                            Category = Attribute.Categories.Collection,
                            TypeName = "Application1.Entity5"
                        };

                        entity.Attributes.Add(attribute);
                    }
                    else
                    {
                        Attribute attribute = new Attribute
                        {
                            Name = string.Format("Field{0}", eid), // No spaces allowed for the name of the attribute
                            Category = Attribute.Categories.String
                        };

                        entity.Attributes.Add(attribute);
                    }
                }

                domain.Entities.Add(entity);
            }

            return domain;
        }

        public DataStore GetCollection(string entity, int start, int limit, DataFilter filter)
        {
            return new DataStore
            {
                Records = _records.Skip(start).Take(limit).ToList(),
                Count = _records.Count
            };
        }

        public IList<DataField> GetObject(string entity, IList<DataField> identifiers)
        {
            return (from r in _records
                    where AreSame(r.Identifiers, identifiers)
                    select r).Single().Fields;
        }

        public IList<DataField> Insert(string entity, DataRecord record)
        {
            record.Identifiers = new List<DataField>
            {
                new DataField
                {
                    Name = "Id",
                    Value = ++_sequence
                }
            };

            _records.Add(record);

            return record.Identifiers;
        }

        public void Update(string entity, DataRecord record)
        {
            // Find the data record by id
            DataRecord rec = (from r in _records
                              where AreSame(r.Identifiers, record.Identifiers)
                              select r).Single();

            rec.Fields = record.Fields; // TODO: Copy the modified fields
        }

        public void Delete(string entity, IList<Data.DataService.DataField> identifiers)
        {
            // Find the data record by id
            DataRecord record = (from r in _records
                                 where AreSame(r.Identifiers, identifiers)
                                 select r).Single();

            // Remove it
            _records.Remove(record);
        }

        public void Set(string entity, string attribute, IList<DataField> identifiers, DataRecord record)
        {
            throw new System.NotImplementedException();
        }

        public IList<DataField> GetObject(string entity, string attribute, IList<DataField> identifiers)
        {
            if (!attribute.Contains("3"))
            {
                return null;
            }
            else
            {
                IList<DataField> fields = new List<DataField>();

                for (int j = 0; j < 20; ++j)
                {
                    int eid = j + 1;

                    DataField field = new DataField
                    {
                        Name = string.Format("Field{0}", eid), // No spaces allowed for the name of the attribute
                        Value = string.Format("complex {0}", eid)
                    };

                    fields.Add(field);
                }

                return fields;
            }
        }

        public void DeleteObject(string entity, string attribute, IList<DataField> identifiers)
        {
            throw new System.NotImplementedException();
        }

        public void Add(string entity, string attribute, IList<DataField> identifiers, DataRecord record)
        {
            throw new System.NotImplementedException();
        }

        public DataStore GetCollection(string entity, string attribute, int start, int limit, IList<DataField> identifiers)
        {
            IList<DataRecord> records = new List<DataRecord>();

            int count = 10000;
            for (int i = 1; i <= count; ++i)
            {
                DataRecord record = new DataRecord
                {
                    Identifiers = new List<DataField>
                    {
                        new DataField
                        {
                            Name = "Id",
                            Value = i
                        }
                    },
                    Fields = new List<DataField>()
                };

                for (int j = 1; j <= 20; ++j)
                {
                    DataField field = new DataField
                    {
                        Name = string.Format("Field{0}", j),
                        Value = string.Format("CollField {0}-{1}", i, j)
                    };

                    record.Fields.Add(field);
                }

                records.Add(record);
            }

            return new DataStore
            {
                Records = records.Skip(start).Take(limit).ToList(),
                Count = records.Count
            };
        }

        public void UpdateCollection(string entity, string attribute, IList<DataField> identifiers, IList<DataField> data, DataFilter filter)
        {
            throw new System.NotImplementedException();
        }

        public void DeleteCollection(string entity, string attribute, IList<DataField> identifiers, DataFilter filter)
        {
            throw new System.NotImplementedException();
        }
    }
}
